#include "EpilParserUtilities.h"


bool EpilParserUtilities::IsBlockFollow( const EpilTokenStream & tokens )
{
	switch( tokens.GetCurrentToken().type )
	{
	case ETT_KwElse:
	case ETT_KwElseif:
	case ETT_KwEnd:
	case ETT_KwUntil:
	case ETT_EndOfStream:
		return true;
	default:
		return false;
	}
}


bool EpilParserUtilities::IsUnaryOperator( const EpilToken & token )
{
	switch( token.type )
	{
	case ETT_OpMinus:
	case ETT_OpLength:
	case ETT_KwNot:
		return true;
	default:
		return false;
	}
}


bool EpilParserUtilities::IsBinaryOperator( const EpilToken & token )
{
	switch( token.type )
	{
	case ETT_OpAdd:
	case ETT_OpMinus:
	case ETT_OpMultiply:
	case ETT_OpDivide:
	case ETT_OpMod:
	case ETT_OpPower:
	case ETT_OpStringConcatenate:
	case ETT_OpUnequal:
	case ETT_OpEqual:
	case ETT_OpLessThan:
	case ETT_OpLessThanOrEqual:
	case ETT_OpGreaterThan:
	case ETT_OpGreaterThanOrEqual:
	case ETT_KwAnd:
	case ETT_KwOr:
		return true;
	default:
		return false;
	}
}


int EpilParserUtilities::GetUnaryOperatorPrecedence( const EpilToken & token )
{
	switch( token.type )
	{
	case ETT_KwNot:
	case ETT_OpLength:
	case ETT_OpMinus:
		return 7;
	default:
		throw runtime_error( "You should pass a unary operator token!" );
	}
}


int EpilParserUtilities::GetBinaryOperatorPrecedence( const EpilToken & token )
{
	// Operator precedence in Lua.
	// Check out the 2.5.6 section of Lua Manual 5.1.

	switch( token.type )
	{
	case ETT_KwOr:
		return 1;
	case ETT_KwAnd:
		return 2;
	case ETT_OpLessThan:
	case ETT_OpLessThanOrEqual:
	case ETT_OpGreaterThan:
	case ETT_OpGreaterThanOrEqual:
	case ETT_OpUnequal:
	case ETT_OpEqual:
		return 3;
	case ETT_OpStringConcatenate:
		return 4;
	case ETT_OpAdd:
	case ETT_OpMinus:
		return 5;
	case ETT_OpMultiply:
	case ETT_OpDivide:
	case ETT_OpMod:
		return 6;
	case ETT_OpPower:
		return 8;
	default:
		throw runtime_error( "You should pass a binary operator token!" );
	}
}


EpilUnaryOperator EpilParserUtilities::TranslateUnaryOperator( const EpilToken & token )
{
	switch( token.type )
	{
	case ETT_OpMinus:
		return EUO_Opposite;
	case ETT_OpLength:
		return EUO_Length;
	case ETT_KwNot:
		return EUO_Not;
	default:
		throw runtime_error( "You should pass a unary operator token!" );
	}
}


EpilBinaryOperator EpilParserUtilities::TranslateBinaryOperator( const EpilToken & token )
{
	switch( token.type )
	{
	case ETT_OpAdd:
		return EBO_Add;
	case ETT_OpMinus:
		return EBO_Minus;
	case ETT_OpMultiply:
		return EBO_Multiply;
	case ETT_OpDivide:
		return EBO_Divide;
	case ETT_OpMod:
		return EBO_Mod;
	case ETT_OpPower:
		return EBO_Power;
	case ETT_OpStringConcatenate:
		return EBO_StringConcatenate;
	case ETT_OpUnequal:
		return EBO_Unequal;
	case ETT_OpEqual:
		return EBO_Equal;
	case ETT_OpLessThan:
		return EBO_LessThan;
	case ETT_OpLessThanOrEqual:
		return EBO_LessThanOrEqual;
	case ETT_OpGreaterThan:
		return EBO_GreaterThan;
	case ETT_OpGreaterThanOrEqual:
		return EBO_GreaterThanOrEqual;
	case ETT_KwAnd:
		return EBO_And;
	case ETT_KwOr:
		return EBO_Or;
	default:
		throw runtime_error( "You should pass a binary operator token!" );
	}
}


int EpilParserUtilities::ParseDecimal( const tstring & str )
{
	tstringstream strStream;
	strStream << str;
	int ret = 0;
	strStream >> ret;
	return ret;
}


double EpilParserUtilities::ParseDouble( const tstring & str )
{
	tstringstream strStream;
	strStream << str;
	double ret = 0;
	strStream >> ret;
	return ret;
}


int EpilParserUtilities::ParseOctal( const tstring & str )
{
	tstringstream strStream;
	strStream << oct << str;
	int ret = 0;
	strStream >> ret;
	return ret;
}


int EpilParserUtilities::ParseHexadecimal( const tstring & str )
{
	tstringstream strStream;
	strStream << hex << str;
	int ret = 0;
	strStream >> ret;
	return ret;
}


double EpilParserUtilities::ParseScientific( const tstring & str )
{
	tstringstream strStream;
	strStream << scientific << str;
	double ret = 0;
	strStream >> ret;
	return ret;
}